// 对于 axios 进行二次封装
import axios from 'axios'

import router from '@/router'
// // 引入进度条 与进度条样式
// import store from '@/store'
import $store from '@/plugins/store'
import $API from '@/plugins/api'
import $modal from '@/plugins/modal'
const getToken = function (): string {
  return $store.shop.getAccessToken() ?? null
}

// axios基本对象配置
const request = axios.create({
  // 配置对象
  // 基础路径 ，发请求的时候 路径当中会出现api
  // baseURL:'http://192.168.87.101:8081/api/',
  baseURL: import.meta.env.VITE_APP_BASE_API,
  // 配置超时时间
  timeout: 5000
})

// 请求拦截器 :在发送请求之前请求拦截器可以检测到
function formatDateForObjectWithDates(obj: any, dateFormat = 'yyyy-MM-dd HH:mm:ss'): any {
  if (obj instanceof Date) {
    // 如果是 Date 类型，将其转换为指定格式的字符串
    const formattedDate = formatDate(obj, dateFormat)
    return formattedDate
  } else if (typeof obj === 'object') {
    // 如果是对象，则递归处理每个属性
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        obj[key] = formatDateForObjectWithDates(obj[key], dateFormat)
      }
    }
  }
  // 返回处理后的对象
  return obj
}
request.interceptors.request.use((config) => {
  // config : 配置对象
  // 进度条开始
  // nprogress.start();
  // 请求带token!
  const token = getToken()
  if (token != null) {
    config.headers.Authorization = `Bearer ${token}` // 配置token在这里
  }
  // 将参数对象中的Date对象转为指定格式这样后端才能转为对应的时间对象
  formatDateForObjectWithDates(config.params, 'yyyy-MM-dd HH:mm:ss')
  formatDateForObjectWithDates(config.data, 'yyyy-MM-dd HH:mm:ss')

  return config
})

// 响应拦截器
request.interceptors.response.use(
  (response) => {
    // 进度条结束
    // nprogress.done();
    return response.data
  },
  async (error) => {
    if (error.response != null && error.response.status === 401) {
      // 当是401时如果存在刷新令牌，那就会尝试刷新令牌，否则跳转到登录页
      console.log('响应拦截器-错误-401')
      if (!$store.shop.isRefreshTokenExpired()) {
        const refreshToken = $store.shop.getRefreshToken()
        // 刷新token
        const result = await $API.merchantAccount.refreshToken(refreshToken)
        console.log('刷新token', result)
        if (result.success) {
          $store.shop.setTokens(result.data)
          return request(error.config)
        }
      }
      console.log('跳转去登录页')
      router.replace('/login')
    } else {
      $modal.msgError('请求失败！' + error.message)
      console.log(error)
    }
  }
)

// SSE
import { EventSourcePolyfill } from 'event-source-polyfill'
import { formatDate } from '@/utils/TimeUtils'

interface EventData<T> {
  messageType: number
  data: T
}

export class SSEConnection<T> {
  private eventSourcePolyfill: EventSourcePolyfill
  constructor(path: string) {
    this.eventSourcePolyfill = new EventSourcePolyfill(import.meta.env.VITE_APP_BASE_API + path, {
      headers: { Authorization: `Bearer ${getToken()}` }
    })
  }
  public onOpen(runnable: () => void) {
    runnable()
    return this
  }
  public onMessage(consumer: (event: EventData<T>) => void) {
    this.eventSourcePolyfill.onmessage = (event) => consumer(JSON.parse(event.data))
    return this
  }
  public onClose(runnable: () => void) {
    runnable()
    return this
  }
}

// 对外暴露
export default request
